import os
import cgi
import datetime
import logging
import urllib
import wsgiref.handlers

from google.appengine.api import mail, memcache, users, xmpp
from google.appengine.ext.webapp import template
from google.appengine.api import mail, memcache, users
from google.appengine.api import urlfetch
from google.appengine.ext import db
from google.appengine.api import images
from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app

# Set the debug level
_DEBUG = True
PAGESIZE = 30

class GreetingUser(db.Model):
  greeting_user = db.UserProperty()
  joined = db.DateTimeProperty(auto_now_add=True)
  picture = db.StringProperty()
  seated = db.StringProperty()
  website = db.StringProperty()
  
class Greeting(db.Model):
  """Models an individual Guestbook entry with an author, content, and date."""
  author = db.UserProperty()
  content = db.StringProperty(multiline=True)
  date = db.DateTimeProperty(auto_now_add=True)

user = users.get_current_user()

class Item(db.Model):
  """Models an individual Guestbook entry with an author, content, and date."""
  author = db.UserProperty()
  content = db.StringProperty(multiline=True)
  date = db.DateTimeProperty(auto_now_add=True)
  vote = db.IntegerProperty(default=1,required=True)
  title = db.StringProperty(multiline=False)
  condition = db.StringProperty()
  yearmade = db.StringProperty()
  sellprice = db.StringProperty()
  photo = db.BlobProperty()
  category = db.StringProperty()   
  INDEX_ONLY = ['author', 'content', 'category'] 
  
class Response(db.Model):
  """Allows responses to comments"""
  author = db.UserProperty()
  content = db.StringProperty(multiline=True)
  inquiry = db.StringProperty()
  date = db.DateTimeProperty(auto_now_add=True)
  vote = db.IntegerProperty(default=1,required=True)
  idea = db.ReferenceProperty(Item,required=True)

user = users.get_current_user()
is_existing_user = Item.all().filter('author = ', user).get()  

def response_count(user):
  responsecount = Response.all().filter('author =', user).count(1000)
  return responsecount
  
def user_comments(user):
  count = Item.all().filter('author =', user).count(10000)
  return count   
  
def guestbook_key(guestbook_name=None):
  '''Constructs a datastore key for a Guestbook entity with guestbook_name.'''
  return db.Key.from_path('Guestbook', guestbook_name or 'default_guestbook')  
  
def buyandsell_key(item_name=None):
  '''Constructs a datastore key for a Buyandsell entity with item_name.'''
  return db.Key.from_path('Buyandsell', item_name or 'default_buyandsell')  
  
class BaseRequestHandler(webapp.RequestHandler):
  '''Base request handler extends webapp.Request handler

     It defines the generate method, which renders a Django template
     in response to a web request
  '''

  def generate(self, template_name, template_values={}):
    '''Generate takes renders and HTML template along with values
       passed to that template

       Args:
         template_name: A string that represents the name of the HTML template
         template_values: A dictionary that associates objects with a string
           assigned to that object to call in the HTML template.  The defualt
           is an empty dictionary.
    '''
    # We check if there is a current user and generate a login or logout URL
    user = users.get_current_user()

    if user:
      log_in_out_url = users.create_logout_url('/')
    else:
      log_in_out_url = users.create_login_url(self.request.path)

    # We'll display the user name if available and the URL on all pages
    values = {'user': user, 'log_in_out_url': log_in_out_url}
    values.update(template_values)

    # Construct the path to the template
    directory = os.path.dirname(__file__)
    path = os.path.join(directory, 'templates', template_name)

    # Respond to the request by rendering the template
    self.response.out.write(template.render(path, values, debug=_DEBUG))
    
class MainRequestHandler(BaseRequestHandler):
  def get(self):
    if users.get_current_user():
      url = users.create_logout_url(self.request.uri)
      url_linktext = 'Logout'
    else:
      url = users.create_login_url(self.request.uri)
      url_linktext = 'Login'

    template_values = {		
      'user_comments': user_comments(users.get_current_user()),	
      'url': url,
      'url_linktext': url_linktext,
      }

    self.generate('index.html', template_values);

class ChatsRequestHandler(BaseRequestHandler):
  def renderChats(self):
    greetings_query = Greeting.all().order('date')
    greetings = greetings_query.fetch(500)

    template_values = {
      'user_comments': user_comments(users.get_current_user()),	
      'greetings': greetings,
    }
    return self.generate('chats.html', template_values)
      
  def getChats(self, useCache=True):
    if useCache is False:
      greetings = self.renderChats()
      if not memcache.set("chat", greetings, 10):
        logging.error("Memcache set failed:")
      return greetings
      
    greetings = memcache.get("chats")
    if greetings is not None:
      return greetings
    else:
      greetings = self.renderChats()
      if not memcache.set("chat", greetings, 10):
        logging.error("Memcache set failed:")
      return greetings
    
  def get(self):
    self.getChats()

  def post(self):
    greeting = Greeting()

    if users.get_current_user():
      greeting.author = users.get_current_user()

    greeting.content = self.request.get('content')
    greeting.put()
    
    self.getChats(False)
    
class ItemsRequestHandler(BaseRequestHandler):
  def renderItems(self):
    items_query = Items.all().order('date')
    items = items_query.fetch(PAGESIZE)

    template_values = {		
      'user_comments': user_comments(users.get_current_user()),	
	  'items': items,
    }
    return self.generate('items.html', template_values)
      
  def getItems(self, useCache=True):
    if useCache is False:
      items = self.renderItems()
      if not memcache.set("item", items, 10):
        logging.error("Memcache set failed:")
      return items
      
    items = memcache.get("items")
    if items is not None:
      return items
    else:
      items = self.renderItems()
      if not memcache.set("item", items, 10):
        logging.error("Memcache set failed:")
      return items
    
  def get(self):
    self.getItems()

  def post(self):
    maxlength=300
    if len(self.request.get("content")) > maxlength:
      self.error(400)
      return
    
    maxtitle=40
    if len(self.request.get("title")) > maxtitle:
      self.error(400)
      return  
    c = self.request.get('category')
    item_name = self.request.get('item_name')
    s = self.request.get('s')
    n = self.request.get('n')
    
    item = Item(category=c, parent=buyandsell_key(item_name))  

    if users.get_current_user():
      item.author = users.get_current_user()        
      item.content = self.request.get('content')
      item.title = self.request.get('title')
      item.condition = self.request.get('condition')
      item.sellprice = self.request.get('sellprice')
      item.yearmade = self.request.get('yearmade')
      photo = images.resize(self.request.get('photo'), 400, 400)
      c = self.request.get('category')
      item.photo = db.Blob(photo)
      item.put()
    
    self.getItems(False)    

class Buyandsell(webapp.RequestHandler):
  def post(self):
    maxlength=300
    if len(self.request.get("content")) > maxlength:
      self.error(400)
      return
    
    maxtitle=40
    if len(self.request.get("title")) > maxtitle:
      self.error(400)
      return
      
    c = self.request.get('category')
    item_name = self.request.get('item_name')
    s = self.request.get('s')
    n = self.request.get('n')
    
    item = Item(category=c, parent=buyandsell_key(item_name))  

    if users.get_current_user():
      item.author = users.get_current_user()        
      item.content = self.request.get('content')
      item.title = self.request.get('title')
      item.condition = self.request.get('condition')
      item.sellprice = self.request.get('sellprice')
      item.yearmade = self.request.get('yearmade')
      photo = images.resize(self.request.get('photo'), 400, 400)
      c = self.request.get('category')
      item.photo = db.Blob(photo)
      item.put()
      self.redirect('/buyandsell?c='+c)
    else:
      self.redirect(users.create_login_url('/?' + urllib.urlencode({'item_name': item_name})))

class Respond(webapp.RequestHandler):
  def post(self):
    item_name = self.request.get('item_name')
    user = users.get_current_user()
    c = self.request.get('category')
    s = self.request.get('s')	
    if user:
      item_id = self.request.get('item_id_respond')
      item_id = int(item_id, 10)
      item = Item.get_by_id(item_id, buyandsell_key())
      if item:
        c = self.request.get('category')
        response = Response(idea = item)
        response.author = users.get_current_user()
        response.content = self.request.get('content')
        response.inquiry = self.request.get('inquiry')
        #mail.send_mail(
        #    user.email(), # from
        #    greeting.author.email(), # to
        #    'MSUchat: %s is %s - %s' % (user, response.inquiry, greeting.title), # subj
        #   'You received a response to your posting.\r\n\r\n%s wrote:\r\n\r\n"%s"' % (user, response.content), # body
        #)
        response.put()      
        self.redirect('/buyandsell?c='+c)
      else:
        self.redirect('/hacks/hacker4.html')
    else:
      self.redirect(users.create_login_url('/?' + urllib.urlencode({'item_name': item_name})))	  

class ItemDeleter(webapp.RequestHandler):
  def post(self):
    item_name = self.request.get('item_name')
    c = self.request.get('category')
    s = self.request.get('s')	
    if user:
      item_id = self.request.get('item_id_delete')
      item_id = int(item_id, 10)
      item = Item.get_by_id(item_id, buyandsell_key())
      if item != None: 
        if user.user_id() == item.author.user_id():
          item.delete()
          self.redirect('/buyandsell?c='+c)
        else:
          self.redirect('/hacks/hacker3.html')
      else:
        self.redirect('/hacks/hacker2.html')
    else:
      self.redirect('/hacks/hacker1.html')
	  
class Image (webapp.RequestHandler):
    def get(self):
      item = db.get(self.request.get("img_id"))
      if item.photo:
          self.response.headers['Content-Type'] = "CorrectMimeType"
          self.response.out.write(item.photo)
      else:
          self.error(404)
      
class EditUserProfileHandler(BaseRequestHandler):
  """This allows a user to edit his or her wiki profile.  The user can upload
     a picture and set a feed URL for personal data
  """
  def get(self, user):
    # Get the user information
    unescaped_user = urllib.unquote(user)
    greeting_user_object = users.User(unescaped_user)
    # Only that user can edit his or her profile


    greeting_user = GreetingUser.gql('WHERE greeting_user = :1', greeting_user_object).get()
    if not greeting_user:
      greeting_user = GreetingUser(greeting_user=greeting_user_object)
      greeting_user.put()

    self.generate('edit_user.html', template_values={'queried_user': greeting_user})

  def post(self, user):
    # Get the user information
    unescaped_user = urllib.unquote(user)
    greeting_user_object = users.User(unescaped_user)
    # Only that user can edit his or her profile
    if users.get_current_user() != greeting_user_object:
      self.redirect('/')

    greeting_user = GreetingUser.gql('WHERE greeting_user = :1', greeting_user_object).get()

    greeting_user.picture = self.request.get('user_picture')
    greeting_user.website = self.request.get('user_website')
    greeting_user.seated = self.request.get('user_seated')
    greeting_user.put()


    self.redirect('/user/%s' % user)
    
class UserProfileHandler(BaseRequestHandler):
  """Allows a user to view another user's profile.  All users are able to
     view this information by requesting http://wikiapp.appspot.com/user/*
  """
  def get(self, user):
    """When requesting the URL, we find out that user's WikiUser information.
       We also retrieve articles written by the user
    """
    # Webob over quotes the request URI, so we have to unquote twice
    unescaped_user = urllib.unquote(urllib.unquote(user))
    
    # Query for the user information
    greeting_user_object = users.User(unescaped_user)
    greeting_user = GreetingUser.gql('WHERE greeting_user = :1', greeting_user_object).get()

    # Generate the user profile
    self.generate('user.html', template_values={'queried_user': greeting_user})

class BuyandsellHandler(webapp.RequestHandler):
    def get(self):
        next = None        
        buyandsell_name=self.request.get('buyandsell_name')        
        items_query = None      
        n = self.request.get('n')
        s = self.request.get('s')
        logging.info("s=" + str(s))        
        user = users.get_current_user() 
        
        if n == "oldest":
          items_query = Item.all().ancestor(buyandsell_key(buyandsell_name)).order('-date')
        elif n == "me":
          items_query = Item.all().ancestor(buyandsell_key(buyandsell_name)).order('date')
        
        if s == "newest":
          items_query = Item.all().ancestor(buyandsell_key(buyandsell_name)).order('-date')          
        elif s == "me":
          items_query = Item.all().ancestor(buyandsell_key(buyandsell_name)).filter('author =', users.get_current_user()).order('-vote')
        elif s == "profile":
          items_query = Item.all().ancestor(buyandsell_key(buyandsell_name)).filter('author =', users.get_current_user()).order('-vote') 
        else:
          items_query = Item.all().ancestor(buyandsell_key(buyandsell_name))

        c = self.request.get('c')
        if c != "":
          items_query = items_query.filter("category =", c)
    
      
        allItems = Item.all()    
        items = items_query.fetch(PAGESIZE + 1)        
        allItems = Item.all().fetch(1000)
        categories = []
        for item in allItems:
          categories.append(item.category)
        categories = set(categories)

        if users.get_current_user():
            url = users.create_logout_url(self.request.uri)
            url_linktext = 'Logout'
        else:
            url = users.create_login_url(self.request.uri)
            url_linktext = 'Login'
            
        template_values = {
            'user_comments': user_comments(users.get_current_user()),	
            'items': items,
            'categories': categories,
            'url': url,
            'url_linktext': url_linktext,
            'user': users.get_current_user(),
            'logged_in': users.get_current_user() != None,
            'c': self.request.get('c') if '' != self.request.get('c') else 'choosecategory',
            's': self.request.get('s') if '' != self.request.get('s') else 'home',
            'n': self.request.get('n') if '' != self.request.get('n') else '',
        }

        path = os.path.join(os.path.dirname(__file__), 'buyandsell.html')
        self.response.out.write(template.render(path, template_values))  

class HomeHandler(webapp.RequestHandler):
   def get(self):
        buyandsell_name=self.request.get('buyandsell_name')        
        items_query = None      
        n = self.request.get('n')
        s = self.request.get('s')
        logging.info("s=" + str(s))        
        user = users.get_current_user() 
        
        if n == "oldest":
          items_query = Item.all().ancestor(buyandsell_key(buyandsell_name)).order('-date')
        elif n == "me":
          items_query = Item.all().ancestor(buyandsell_key(buyandsell_name)).order('date')
        
        if s == "newest":
          items_query = Item.all().ancestor(buyandsell_key(buyandsell_name)).order('-date')          
        elif s == "me":
          items_query = Item.all().ancestor(buyandsell_key(buyandsell_name)).filter('author =', users.get_current_user()).order('-vote')
        elif s == "profile":
          items_query = Item.all().ancestor(buyandsell_key(buyandsell_name)).filter('author =', users.get_current_user()).order('-vote') 
        else:
          items_query = Item.all().ancestor(buyandsell_key(buyandsell_name))

        c = self.request.get('c')
        if c != "":
          items_query = items_query.filter("category =", c)
    
      
        allItems = Item.all()    
        items = items_query.fetch(30)        
        allItems = Item.all().fetch(1000)
        categories = []
        for item in allItems:
          categories.append(item.category)
        categories = set(categories)

        if users.get_current_user():
            url = users.create_logout_url(self.request.uri)
            url_linktext = 'Logout'
        else:
            url = users.create_login_url(self.request.uri)
            url_linktext = 'Login'
            
        template_values = {
            'user_comments': user_comments(users.get_current_user()),
            'items': items,
            'categories': categories,
            'url': url,
            'url_linktext': url_linktext,
            'user': users.get_current_user(),
            'logged_in': users.get_current_user() != None,
            'c': self.request.get('c') if '' != self.request.get('c') else 'choosecategory',
            's': self.request.get('s') if '' != self.request.get('s') else 'home',
            'n': self.request.get('n') if '' != self.request.get('n') else '',
        }

        path = os.path.join(os.path.dirname(__file__), 'home.html')
        self.response.out.write(template.render(path, template_values))            
                                                
application = webapp.WSGIApplication(
                                     [('/', HomeHandler),
                                      ('/img', Image),
                                      ('/sign', Buyandsell),
									  ('/deleter', ItemDeleter),
                                      ('/buyandsell', BuyandsellHandler), 
									  ('/respond', Respond),
                                      ('/completethesentence', MainRequestHandler), 
                                      ('/getchats', ChatsRequestHandler),
                                      ('/getitems', ItemsRequestHandler),
                                      ('/user/([^/]+)', UserProfileHandler),
                                      ('/edituser/([^/]+)', EditUserProfileHandler)],
                                     debug=True)

def main():
  run_wsgi_app(application)

if __name__ == "__main__":
  main()